<!DOCTYPE html>
<html lang="en" data-color-mode="auto" data-light-theme="light" data-dark-theme="dark"  data-a11y-animated-images="system" data-a11y-link-underlines="false">
<head>

    <meta charset="utf-8">
    <link rel="dns-prefetch" href="https://github.githubassets.com">
    <link rel="dns-prefetch" href="https://avatars.githubusercontent.com">
    <link rel="dns-prefetch" href="https://github-cloud.s3.amazonaws.com">
    <link rel="dns-prefetch" href="https://user-images.githubusercontent.com/">
    <link rel="preconnect" href="https://github.githubassets.com" crossorigin>
    <link rel="preconnect" href="https://avatars.githubusercontent.com">

    <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/light-8cafbcbd78f4.css" />
    <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/dark-31dc14e38457.css" />
    <link data-color-theme="dark_dimmed" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_dimmed-71414d661fe2.css" />
    <link data-color-theme="dark_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_high_contrast-ba96c7f1d660.css" />
    <link data-color-theme="dark_colorblind" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_colorblind-7471c22cdb6a.css" />
    <link data-color-theme="light_colorblind" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/light_colorblind-80180bed15ed.css" />
    <link data-color-theme="light_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/light_high_contrast-e89b9cdecb75.css" />
    <link data-color-theme="light_tritanopia" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/light_tritanopia-77f15e9154df.css" />
    <link data-color-theme="dark_tritanopia" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_tritanopia-f598f8dd18ae.css" />

    <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-primitives-fb1d51d1ef66.css" />
    <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-8f43f7721dc7.css" />
    <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/global-1c4d2d83ff46.css" />
    <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/github-422d7f955a64.css" />
    <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/code-21c43201dfae.css" />

    <title>GitHub - ponfee/disjob: Disjob is a distributed job scheduling framework</title>

    <link rel="assets" href="https://github.githubassets.com/">
    <link rel="search" type="application/opensearchdescription+xml" href="https://github.com/opensearch.xml" title="GitHub">
    <link rel="fluid-icon" href="https://github.com/fluidicon.png" title="GitHub">
    <link rel="canonical" href="https://github.com/ponfee/disjob" data-turbo-transient>
    <link rel="mask-icon" href="https://github.githubassets.com/pinned-octocat.svg" color="#000000">
    <link rel="alternate icon" class="js-site-favicon" type="image/png" href="https://github.githubassets.com/favicons/favicon.png">
    <link rel="icon" class="js-site-favicon" type="image/svg+xml" href="https://github.githubassets.com/favicons/favicon.svg">
    <link rel="manifest" href="https://github.com/manifest.json" crossOrigin="use-credentials">


</head>
<!--
    /dromara/disjob/blob/  =>  https://github.com/dromara/disjob/blob/
    /dromara/disjob/raw/   =>  https://raw.githubusercontent.com/dromara/disjob/
-->

<body class="logged-out env-production page-responsive" style="word-wrap: break-word;">

<div class="clearfix container-xl mt-4 px-md-4 px-lg-5 px-3">














    <readme-toc>

        <div id="readme" class="Box md js-code-block-container js-code-nav-container js-tagsearch-file Box--responsive"
             data-tagsearch-path="README.md"
             data-tagsearch-lang="Markdown">

            <div class="d-flex  js-sticky js-position-sticky top-0 border-top-0 border-bottom p-2 flex-items-center flex-justify-between color-bg-default rounded-top-2"  style="position: sticky; z-index: 30;" >
                <div class="d-flex flex-items-center">
                    <details
                        data-target="readme-toc.trigger"
                        data-menu-hydro-click="{&quot;event_type&quot;:&quot;repository_toc_menu.click&quot;,&quot;payload&quot;:{&quot;target&quot;:&quot;trigger&quot;,&quot;repository_id&quot;:546544025,&quot;originating_url&quot;:&quot;https://github.com/dromara/disjob/tree/master&quot;,&quot;user_id&quot;:null}}"
                        data-menu-hydro-click-hmac="bd7148863bbd9db4664f052bbab7073356738d9a3bbd491a690a8ffbff67444b"
                        class="dropdown details-reset details-overlay"
                    >
                        <summary
                            class="btn btn-octicon m-0 mr-2 p-2"
                            aria-haspopup="true"
                            aria-label="Table of Contents">
                            <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-list-unordered">
                                <path d="M5.75 2.5h8.5a.75.75 0 0 1 0 1.5h-8.5a.75.75 0 0 1 0-1.5Zm0 5h8.5a.75.75 0 0 1 0 1.5h-8.5a.75.75 0 0 1 0-1.5Zm0 5h8.5a.75.75 0 0 1 0 1.5h-8.5a.75.75 0 0 1 0-1.5ZM2 14a1 1 0 1 1 0-2 1 1 0 0 1 0 2Zm1-6a1 1 0 1 1-2 0 1 1 0 0 1 2 0ZM2 4a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z"></path>
                            </svg>
                        </summary>


                        <details-menu class="SelectMenu" role="menu">
                            <div class="SelectMenu-modal rounded-3 mt-1" style="max-height:340px;">

                                <div class="SelectMenu-filter">
                                    <input
                                        class="SelectMenu-input form-control js-filterable-field"
                                        id="toc-filter-field"
                                        type="text"
                                        autocomplete="off"
                                        spellcheck="false"
                                        autofocus
                                        placeholder="Filter headings"
                                        aria-label="Filter headings">
                                </div>

                                <div class="SelectMenu-list SelectMenu-list--borderless p-2" style="overscroll-behavior: contain;" data-filterable-for="toc-filter-field" data-filterable-type="substring">
                                    <a role="menuitem" class="filter-item SelectMenu-item ws-normal wb-break-word line-clamp-2 py-1 " style="-webkit-box-orient: vertical; padding-left: 24px;" data-action="click:readme-toc#blur" data-targets="readme-toc.entries" data-hydro-click="{&quot;event_type&quot;:&quot;repository_toc_menu.click&quot;,&quot;payload&quot;:{&quot;target&quot;:&quot;entry&quot;,&quot;repository_id&quot;:546544025,&quot;originating_url&quot;:&quot;https://github.com/dromara/disjob/tree/master&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="c911c4fd45543ab3a017ab6c1e8ac4b8c511141af52e228434dd83a6df017d27" href="#architecture">Architecture</a>
                                    <a role="menuitem" class="filter-item SelectMenu-item ws-normal wb-break-word line-clamp-2 py-1 " style="-webkit-box-orient: vertical; padding-left: 24px;" data-action="click:readme-toc#blur" data-targets="readme-toc.entries" data-hydro-click="{&quot;event_type&quot;:&quot;repository_toc_menu.click&quot;,&quot;payload&quot;:{&quot;target&quot;:&quot;entry&quot;,&quot;repository_id&quot;:546544025,&quot;originating_url&quot;:&quot;https://github.com/dromara/disjob/tree/master&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="c911c4fd45543ab3a017ab6c1e8ac4b8c511141af52e228434dd83a6df017d27" href="#features">Features</a>
                                    <a role="menuitem" class="filter-item SelectMenu-item ws-normal wb-break-word line-clamp-2 py-1 " style="-webkit-box-orient: vertical; padding-left: 24px;" data-action="click:readme-toc#blur" data-targets="readme-toc.entries" data-hydro-click="{&quot;event_type&quot;:&quot;repository_toc_menu.click&quot;,&quot;payload&quot;:{&quot;target&quot;:&quot;entry&quot;,&quot;repository_id&quot;:546544025,&quot;originating_url&quot;:&quot;https://github.com/dromara/disjob/tree/master&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="c911c4fd45543ab3a017ab6c1e8ac4b8c511141af52e228434dd83a6df017d27" href="#download-from-maven-central">Download From Maven Central</a>
                                    <a role="menuitem" class="filter-item SelectMenu-item ws-normal wb-break-word line-clamp-2 py-1 " style="-webkit-box-orient: vertical; padding-left: 24px;" data-action="click:readme-toc#blur" data-targets="readme-toc.entries" data-hydro-click="{&quot;event_type&quot;:&quot;repository_toc_menu.click&quot;,&quot;payload&quot;:{&quot;target&quot;:&quot;entry&quot;,&quot;repository_id&quot;:546544025,&quot;originating_url&quot;:&quot;https://github.com/dromara/disjob/tree/master&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="c911c4fd45543ab3a017ab6c1e8ac4b8c511141af52e228434dd83a6df017d27" href="#build-from-source">Build From Source</a>
                                    <a role="menuitem" class="filter-item SelectMenu-item ws-normal wb-break-word line-clamp-2 py-1 " style="-webkit-box-orient: vertical; padding-left: 24px;" data-action="click:readme-toc#blur" data-targets="readme-toc.entries" data-hydro-click="{&quot;event_type&quot;:&quot;repository_toc_menu.click&quot;,&quot;payload&quot;:{&quot;target&quot;:&quot;entry&quot;,&quot;repository_id&quot;:546544025,&quot;originating_url&quot;:&quot;https://github.com/dromara/disjob/tree/master&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="c911c4fd45543ab3a017ab6c1e8ac4b8c511141af52e228434dd83a6df017d27" href="#quick-start">Quick Start</a>
                                    <a role="menuitem" class="filter-item SelectMenu-item ws-normal wb-break-word line-clamp-2 py-1 " style="-webkit-box-orient: vertical; padding-left: 24px;" data-action="click:readme-toc#blur" data-targets="readme-toc.entries" data-hydro-click="{&quot;event_type&quot;:&quot;repository_toc_menu.click&quot;,&quot;payload&quot;:{&quot;target&quot;:&quot;entry&quot;,&quot;repository_id&quot;:546544025,&quot;originating_url&quot;:&quot;https://github.com/dromara/disjob/tree/master&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="c911c4fd45543ab3a017ab6c1e8ac4b8c511141af52e228434dd83a6df017d27" href="#user-guide">User guide</a>
                                    <a role="menuitem" class="filter-item SelectMenu-item ws-normal wb-break-word line-clamp-2 py-1 text-emphasized" style="-webkit-box-orient: vertical; padding-left: 12px;" data-action="click:readme-toc#blur" data-targets="readme-toc.entries" data-hydro-click="{&quot;event_type&quot;:&quot;repository_toc_menu.click&quot;,&quot;payload&quot;:{&quot;target&quot;:&quot;entry&quot;,&quot;repository_id&quot;:546544025,&quot;originating_url&quot;:&quot;https://github.com/dromara/disjob/tree/master&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="c911c4fd45543ab3a017ab6c1e8ac4b8c511141af52e228434dd83a6df017d27" href="#example">Example</a>
                                    <a role="menuitem" class="filter-item SelectMenu-item ws-normal wb-break-word line-clamp-2 py-1 " style="-webkit-box-orient: vertical; padding-left: 24px;" data-action="click:readme-toc#blur" data-targets="readme-toc.entries" data-hydro-click="{&quot;event_type&quot;:&quot;repository_toc_menu.click&quot;,&quot;payload&quot;:{&quot;target&quot;:&quot;entry&quot;,&quot;repository_id&quot;:546544025,&quot;originating_url&quot;:&quot;https://github.com/dromara/disjob/tree/master&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="c911c4fd45543ab3a017ab6c1e8ac4b8c511141af52e228434dd83a6df017d27" href="#contributing">Contributing</a>
                                    <a role="menuitem" class="filter-item SelectMenu-item ws-normal wb-break-word line-clamp-2 py-1 " style="-webkit-box-orient: vertical; padding-left: 24px;" data-action="click:readme-toc#blur" data-targets="readme-toc.entries" data-hydro-click="{&quot;event_type&quot;:&quot;repository_toc_menu.click&quot;,&quot;payload&quot;:{&quot;target&quot;:&quot;entry&quot;,&quot;repository_id&quot;:546544025,&quot;originating_url&quot;:&quot;https://github.com/dromara/disjob/tree/master&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="c911c4fd45543ab3a017ab6c1e8ac4b8c511141af52e228434dd83a6df017d27" href="#communication">Communication</a>
                                    <a role="menuitem" class="filter-item SelectMenu-item ws-normal wb-break-word line-clamp-2 py-1 " style="-webkit-box-orient: vertical; padding-left: 24px;" data-action="click:readme-toc#blur" data-targets="readme-toc.entries" data-hydro-click="{&quot;event_type&quot;:&quot;repository_toc_menu.click&quot;,&quot;payload&quot;:{&quot;target&quot;:&quot;entry&quot;,&quot;repository_id&quot;:546544025,&quot;originating_url&quot;:&quot;https://github.com/dromara/disjob/tree/master&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="c911c4fd45543ab3a017ab6c1e8ac4b8c511141af52e228434dd83a6df017d27" href="#todo-list">Todo List</a>
                                </div>
                            </div>
                        </details-menu>
                    </details>

                    <h2 class="Box-title">
                        <a href="#readme" data-view-component="true" class="Link--primary Link">README.md</a>
                    </h2>
                </div>
            </div>

            <div data-target="readme-toc.content" class="Box-body px-5 pb-5">
                <article class="markdown-body entry-content container-lg" itemprop="text"><h1 tabindex="-1" dir="auto"><a id="user-content-----" class="anchor" aria-hidden="true" tabindex="-1" href="#----"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a><a target="_blank" rel="noopener noreferrer" href="https://github.com/dromara/disjob/blob/master/docs/images/logo.png"><img src="https://raw.githubusercontent.com/dromara/disjob/master/docs/images/logo.png" width="125" alt="Logo" style="max-width: 100%;"></a> <a href="https://www.apache.org/licenses/LICENSE-2.0.html" rel="nofollow"><img src="https://camo.githubusercontent.com/20b3bc1c34ed71700bd0fc067de4d50e73468def345f89780f839e516cacf8b0/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4170616368652d2d322e302d677265656e2e737667" alt="License" data-canonical-src="https://img.shields.io/badge/license-Apache--2.0-green.svg" style="max-width: 100%;"></a> <a href="https://www.oracle.com/java/technologies/downloads/#java8" rel="nofollow"><img src="https://camo.githubusercontent.com/491e42a3617b89ac8f08a5b249f31d79bd50f7b268e547701840c82d0c9de759/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6a646b2d382b2d677265656e2e737667" alt="JDK" data-canonical-src="https://img.shields.io/badge/jdk-8+-green.svg" style="max-width: 100%;"></a> <a href="https://central.sonatype.com/namespace/cn.ponfee" rel="nofollow"><img src="https://camo.githubusercontent.com/ab42b27697109a86682666b94f539136f355e71b4e5693a641679bfd0f02ae6e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6d6176656e2d2d63656e7472616c2d322e302e322d6f72616e67652e7376673f7374796c653d706c6173746963266c6f676f3d6170616368656d6176656e" alt="Maven Central" data-canonical-src="https://img.shields.io/badge/maven--central-2.0.2-orange.svg?style=plastic&amp;logo=apachemaven" style="max-width: 100%;"></a> <a href="https://github.com/dromara/disjob/actions"><img src="https://github.com/dromara/disjob/workflows/build/badge.svg" alt="Build status" style="max-width: 100%;"></a></h1>
                    <p dir="auto"><strong><code>简体中文</code></strong> | <a href="https://github.com/dromara/disjob/blob/master/README.en.md">English</a></p>
                    <p dir="auto">一个分布式的任务调度框架，除了具备常规的分布式任务调度功能外，还提供：暂停/取消运行中的任务、恢复执行被暂停的任务、任务拆分、失败重试、广播任务、任务依赖、工作流任务(DAG)、管理器与执行器分离部署、Web管理后台等能力。</p>
                    <p dir="auto">轻量级，简单易用，特别适合长任务的执行。有较好的伸缩性、扩展性、稳定性，历经生产检验。</p>
                    <h2 tabindex="-1" dir="auto"><a id="user-content-architecture" class="anchor" aria-hidden="true" tabindex="-1" href="#architecture"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a>Architecture</h2>
                    <ul dir="auto">
                        <li>架构图</li>
                    </ul>
                    <p dir="auto"><a target="_blank" rel="noopener noreferrer" href="https://github.com/dromara/disjob/blob/master/docs/images/architecture.jpg"><img src="https://raw.githubusercontent.com/dromara/disjob/master/docs/images/architecture.jpg" alt="Architecture" style="max-width: 100%;"></a></p>
                    <ul dir="auto">
                        <li>工程结构</li>
                    </ul>
                    <div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="disjob                                        # 主项目
├── disjob-admin                              # 基于Ruoyi框架二次开发的Disjob管理后台
├── disjob-bom                                # Maven project bom module
├── disjob-common                             # 公共的工具类模块
├── disjob-core                               # 任务调度相关的核心类（如数据模型、枚举类、抽象层接口等）
├── disjob-dispatch                           # 任务派发模块
│   ├── disjob-dispatch-api                   # 任务派发的抽象接口层
│   ├── disjob-dispatch-http                  # 任务派发的Http实现
│   └── disjob-dispatch-redis                 # 任务派发的Redis实现
├── disjob-id                                 # 分布式ID生成模块
├── disjob-registry                           # Server(Supervisor &amp; Worker)注册模块
│   ├── disjob-registry-api                   # Server注册的抽象接口层
│   ├── disjob-registry-consul                # Server注册的Consul实现
│   ├── disjob-registry-etcd                  # Server注册的Etcd实现
│   ├── disjob-registry-nacos                 # Server注册的Nacos实现
│   ├── disjob-registry-redis                 # Server注册的Redis实现
│   └── disjob-registry-zookeeper             # Server注册的Zookeeper实现
├── disjob-reports                            # 聚合各个模块的测试覆盖率报告
├── disjob-samples                            # Samples项目
│   ├── disjob-samples-common                 # 使用范例中用到的公共代码及公共配置文件
│   ├── disjob-samples-merged-springboot      # Supervisor与Worker合并部署的范例（Spring-boot应用）
│   ├── disjob-samples-supervisor-springboot  # Supervisor单独部署的范例（Spring-boot应用）
│   ├── disjob-samples-worker-frameless       # Worker单独部署的范例（普通Java-main应用）
│   └── disjob-samples-worker-springboot      # Worker单独部署的范例（Spring-boot应用）
├── disjob-supervisor                         # Supervisor代码
├── disjob-test                               # 用于辅助测试
└── disjob-worker                             # Worker代码"><pre lang="text" class="notranslate"><code>disjob                                        # 主项目
├── disjob-admin                              # 基于Ruoyi框架二次开发的Disjob管理后台
├── disjob-bom                                # Maven project bom module
├── disjob-common                             # 公共的工具类模块
├── disjob-core                               # 任务调度相关的核心类（如数据模型、枚举类、抽象层接口等）
├── disjob-dispatch                           # 任务派发模块
│   ├── disjob-dispatch-api                   # 任务派发的抽象接口层
│   ├── disjob-dispatch-http                  # 任务派发的Http实现
│   └── disjob-dispatch-redis                 # 任务派发的Redis实现
├── disjob-id                                 # 分布式ID生成模块
├── disjob-registry                           # Server(Supervisor &amp; Worker)注册模块
│   ├── disjob-registry-api                   # Server注册的抽象接口层
│   ├── disjob-registry-consul                # Server注册的Consul实现
│   ├── disjob-registry-etcd                  # Server注册的Etcd实现
│   ├── disjob-registry-nacos                 # Server注册的Nacos实现
│   ├── disjob-registry-redis                 # Server注册的Redis实现
│   └── disjob-registry-zookeeper             # Server注册的Zookeeper实现
├── disjob-reports                            # 聚合各个模块的测试覆盖率报告
├── disjob-samples                            # Samples项目
│   ├── disjob-samples-common                 # 使用范例中用到的公共代码及公共配置文件
│   ├── disjob-samples-merged-springboot      # Supervisor与Worker合并部署的范例（Spring-boot应用）
│   ├── disjob-samples-supervisor-springboot  # Supervisor单独部署的范例（Spring-boot应用）
│   ├── disjob-samples-worker-frameless       # Worker单独部署的范例（普通Java-main应用）
│   └── disjob-samples-worker-springboot      # Worker单独部署的范例（Spring-boot应用）
├── disjob-supervisor                         # Supervisor代码
├── disjob-test                               # 用于辅助测试
└── disjob-worker                             # Worker代码
</code></pre></div>
                    <h2 tabindex="-1" dir="auto"><a id="user-content-features" class="anchor" aria-hidden="true" tabindex="-1" href="#features"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a>Features</h2>
                    <ul dir="auto">
                        <li>分为管理器(Supervisor)和执行器(Worker)两种角色，Supervisor与Worker可分离部署</li>
                        <li>Supervisor与Worker通过注册中心相互发现，支持的注册中心有：Redis、Consul、Nacos、Zookeeper、Etcd</li>
                        <li>Supervisor负责生成任务，把任务派发给Worker执行，支持的任务派发方式有：Redis、Http</li>
                        <li>需要指定Job的分组(job-group)，Job的任务只会派发给指定组的Worker执行</li>
                        <li>提供拆分任务的能力，重写拆分方法<a href="https://github.com/dromara/disjob/blob/master/disjob-core/src/main/java/cn/ponfee/disjob/core/handle/JobSplitter.java">JobHandler#split</a>即可拆分为多个任务，实现分布式任务及并行执行</li>
                        <li>支持暂停和取消运行中的任务，已暂停的任务可恢复继续执行，执行失败的任务支持重试</li>
                        <li>支持任务保存(savepoint)其执行状态，让手动或异常暂停的任务能从上一次的执行状态中恢复继续执行</li>
                        <li>任务在执行时若抛出<a href="https://github.com/dromara/disjob/blob/master/disjob-core/src/main/java/cn/ponfee/disjob/core/exception/PauseTaskException.java">PauseTaskException</a>，会暂停对应实例下的全部任务(包括分布在不同worker机器中的任务)</li>
                        <li>支持广播任务，广播任务会派发给job-group下的所有worker执行</li>
                        <li>支持Job间的依赖，多个Job配置好依赖关系后便会按既定的依赖顺序依次执行</li>
                        <li>支持DAG工作流，可把jobHandler配置为复杂的DAG表达式，如：A-&gt;B,C,(D-&gt;E)-&gt;D,F-&gt;G</li>
                        <li>提供Web管理后台，通过界面进行作业配置，任务监控等</li>
                    </ul>
                    <h2 tabindex="-1" dir="auto"><a id="user-content-download-from-maven-central" class="anchor" aria-hidden="true" tabindex="-1" href="#download-from-maven-central"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a><a href="https://central.sonatype.com/namespace/cn.ponfee" rel="nofollow">Download From Maven Central</a></h2>
                    <div class="highlight highlight-text-xml notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="&lt;dependency&gt;
  &lt;groupId&gt;cn.ponfee&lt;/groupId&gt;
  &lt;artifactId&gt;disjob-{xxx}&lt;/artifactId&gt;
  &lt;version&gt;2.0.2&lt;/version&gt;
&lt;/dependency&gt;"><pre>&lt;<span class="pl-ent">dependency</span>&gt;
  &lt;<span class="pl-ent">groupId</span>&gt;cn.ponfee&lt;/<span class="pl-ent">groupId</span>&gt;
  &lt;<span class="pl-ent">artifactId</span>&gt;disjob-{xxx}&lt;/<span class="pl-ent">artifactId</span>&gt;
  &lt;<span class="pl-ent">version</span>&gt;2.0.2&lt;/<span class="pl-ent">version</span>&gt;
&lt;/<span class="pl-ent">dependency</span>&gt;</pre></div>
                    <h2 tabindex="-1" dir="auto"><a id="user-content-build-from-source" class="anchor" aria-hidden="true" tabindex="-1" href="#build-from-source"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a>Build From Source</h2>
                    <div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="./mvnw clean install -DskipTests -Dcheckstyle.skip=true -Dmaven.javadoc.skip=true -U"><pre>./mvnw clean install -DskipTests -Dcheckstyle.skip=true -Dmaven.javadoc.skip=true -U</pre></div>
                    <h2 tabindex="-1" dir="auto"><a id="user-content-quick-start" class="anchor" aria-hidden="true" tabindex="-1" href="#quick-start"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a>Quick Start</h2>
                    <ol dir="auto">
                        <li>在开发工具中分别导入项目（分为三个独立的项目，共用一个<code>git</code>仓库）</li>
                    </ol>
                    <ul dir="auto">
                        <li><a href="https://github.com/dromara/disjob/blob/master/pom.xml">主项目—disjob</a></li>
                        <li><a href="https://github.com/dromara/disjob/blob/master/disjob-samples/pom.xml">范例项目—disjob-samples</a></li>
                        <li><a href="https://github.com/dromara/disjob/blob/master/disjob-admin/pom.xml">管理后台—disjob-admin</a></li>
                    </ul>
                    <ol start="2" dir="auto">
                        <li>启动以下各应用组成分布式调度集群</li>
                    </ol>
                    <blockquote>
                        <p dir="auto">已配置不同的端口可同时启动。可以在开发工具中运行Java类，也可通过<code>java -jar</code>命令运行构建好的jar包。</p>
                    </blockquote>
                    <ul dir="auto">
                        <li><a href="https://github.com/dromara/disjob/blob/master/disjob-samples/disjob-samples-common/src/test/java/cn/ponfee/disjob/samples/MysqlAndRedisServerStarter.java">启动内嵌的本地Mysql &amp; Redis</a>
                            <ul dir="auto">
                                <li>MacOS系统若报<code>MariaDB</code>的“<a href="https://github.com/dromara/disjob/blob/master/disjob-test/src/main/DB/MariaDB/MariaDB.md">Library not loaded</a>”错误时参考</li>
                                <li>使用客户端工具连接mysql时，用户名为<code>root</code>，无需密码</li>
                                <li>启动时已经自动执行了初始化的SQL脚本</li>
                            </ul>
                        </li>
                        <li><a href="https://github.com/dromara/disjob/blob/master/disjob-samples/disjob-samples-worker-springboot/src/main/java/cn/ponfee/disjob/samples/worker/WorkerApplication.java">启动Worker单独部署的Spring-boot应用</a></li>
                        <li><a href="https://github.com/dromara/disjob/blob/master/disjob-samples/disjob-samples-worker-frameless/src/main/java/cn/ponfee/disjob/samples/worker/WorkerFramelessMain.java">启动Worker单独部署的普通Java-main应用</a></li>
                        <li><a href="https://github.com/dromara/disjob/blob/master/disjob-samples/disjob-samples-merged-springboot/src/main/java/cn/ponfee/disjob/samples/merged/MergedApplication.java">启动Supervisor+Worker合并部署的Spring-boot应用</a></li>
                        <li><a href="https://github.com/dromara/disjob/blob/master/disjob-samples/disjob-samples-supervisor-springboot/src/main/java/cn/ponfee/disjob/samples/supervisor/SupervisorApplication.java">启动Supervisor单独部署的Spring-boot应用</a></li>
                        <li><a href="https://github.com/dromara/disjob/blob/master/disjob-admin/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java">启动Admin管理后台的Spring-boot应用</a></li>
                    </ul>
                    <ol start="3" dir="auto">
                        <li>登录管理后台</li>
                    </ol>
                    <ul dir="auto">
                        <li>浏览器访问【 <a href="http://127.0.0.1:80/" rel="nofollow">http://127.0.0.1:80/</a> 】登录管理后台，用户名/密码：<code>admin</code>/<code>admin123</code></li>
                        <li>登录后在左侧菜单栏找到<code>调度管理</code>菜单，即可使用调度管理功能</li>
                        <li>调度配置：作业(job)配置，包括查看、新增、修改、删除、触发、禁用等</li>
                        <li>调度实例：job具体时间点要触发执行的实例(instance)，一个实例被拆分成若干个任务(task)
                            <ul dir="auto">
                                <li>第一个分页表格为<code>查询root实例并支持下钻</code>，root是指首次触发的实例，包括：普通的非重试实例、工作流(DAG)的lead实例、依赖关系的第一个实例</li>
                                <li>鼠标向下滚动页面后看到的第二个分页表格为<code>查询所有实例</code></li>
                            </ul>
                        </li>
                    </ul>
                    <ol start="4" dir="auto">
                        <li>链接地址</li>
                    </ol>
                    <ul dir="auto">
                        <li>管理后台演示地址：【 <a href="http://ponfee.cn:8000/" rel="nofollow">http://ponfee.cn:8000/</a> 】，用户名/密码：<code>disjob</code>/<code>disjob123</code></li>
                        <li>在线文档地址：<code>正在建设中，敬请期待！</code></li>
                    </ul>
                    <h2 tabindex="-1" dir="auto"><a id="user-content-user-guide" class="anchor" aria-hidden="true" tabindex="-1" href="#user-guide"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a>User guide</h2>
                    <ol dir="auto">
                        <li>项目包含两个SQL脚本</li>
                    </ol>
                    <ul dir="auto">
                        <li><a href="https://github.com/dromara/disjob/blob/master/mysql-disjob.sql">核心框架的SQL脚本</a></li>
                        <li><a href="https://github.com/dromara/disjob/blob/master/disjob-admin/mysql-disjob_admin.sql">管理后台的SQL脚本</a></li>
                    </ul>
                    <ol start="2" dir="auto">
                        <li>在Maven pom文件中更改<code>注册中心disjob-registry-{xxx}</code>和<code>任务派发disjob-dispatch-{xxx}</code>的具体实现</li>
                    </ol>
                    <ul dir="auto">
                        <li><a href="https://github.com/dromara/disjob/blob/master/disjob-samples/disjob-samples-common/pom.xml">Samples项目</a></li>
                        <li><a href="https://github.com/dromara/disjob/blob/master/disjob-admin/ruoyi-disjob/pom.xml">Admin项目</a></li>
                        <li>默认使用<code>disjob-registry-redis</code>做注册中心，<code>disjob-dispatch-http</code>做任务派发</li>
                    </ul>
                    <ol start="3" dir="auto">
                        <li>Samples项目配置文件</li>
                    </ol>
                    <ul dir="auto">
                        <li><a href="https://github.com/dromara/disjob/blob/master/disjob-samples/conf-supervisor/application-mysql.yml">Supervisor角色Mysql配置</a></li>
                        <li><a href="https://github.com/dromara/disjob/blob/master/disjob-samples/conf-supervisor/application-supervisor.yml">Supervisor角色核心配置</a></li>
                        <li><a href="https://github.com/dromara/disjob/blob/master/disjob-samples/conf-worker/application-worker.yml">Worker角色核心配置</a>（Spring-boot应用）</li>
                        <li><a href="https://github.com/dromara/disjob/blob/master/disjob-samples/disjob-samples-worker-frameless/src/main/resources/worker-conf.yml">Worker角色核心配置</a>（普通Java-main应用）</li>
                        <li><a href="https://github.com/dromara/disjob/blob/master/disjob-samples/disjob-samples-common/src/main/resources/application-redis.yml">Redis配置</a>（Worker与Supervisor共用，做注册中心或任务派发都使用该配置）</li>
                        <li><a href="https://github.com/dromara/disjob/blob/master/disjob-samples/disjob-samples-common/src/main/resources/application-web.yml">Spring-boot Web相关配置</a>（Worker与Supervisor共用）</li>
                    </ul>
                    <ol start="4" dir="auto">
                        <li>Admin项目配置文件</li>
                    </ol>
                    <ul dir="auto">
                        <li><a href="https://github.com/dromara/disjob/blob/master/disjob-admin/ruoyi-disjob/src/main/resources/application-disjob-mysql.yml">Supervisor角色Mysql配置</a></li>
                        <li><a href="https://github.com/dromara/disjob/blob/master/disjob-admin/ruoyi-disjob/src/main/resources/application-disjob-redis.yml">Redis配置</a>（Worker与Supervisor共用，做注册中心或任务派发都使用该配置）</li>
                        <li><a href="https://github.com/dromara/disjob/blob/master/disjob-admin/ruoyi-admin/src/main/resources/application-druid.yml">管理后台系统Mysql配置</a></li>
                        <li><a href="https://github.com/dromara/disjob/blob/master/disjob-admin/ruoyi-disjob/src/main/java/cn/ponfee/disjob/admin/DisjobAdminConfiguration.java">可加@EnableWorker注解启用Worker角色</a>（管理后台必须启用Supervisor角色）</li>
                    </ul>
                    <ol start="5" dir="auto">
                        <li>各注册中心配置类参考（Redis使用Spring-boot自带的配置方式）</li>
                    </ol>
                    <ul dir="auto">
                        <li><a href="https://github.com/dromara/disjob/blob/master/disjob-registry/disjob-registry-consul/src/main/java/cn/ponfee/disjob/registry/consul/configuration/ConsulRegistryProperties.java">Consul</a></li>
                        <li><a href="https://github.com/dromara/disjob/blob/master/disjob-registry/disjob-registry-zookeeper/src/main/java/cn/ponfee/disjob/registry/zookeeper/configuration/ZookeeperRegistryProperties.java">Zookeeper</a></li>
                        <li><a href="https://github.com/dromara/disjob/blob/master/disjob-registry/disjob-registry-nacos/src/main/java/cn/ponfee/disjob/registry/nacos/configuration/NacosRegistryProperties.java">Nacos</a></li>
                        <li><a href="https://github.com/dromara/disjob/blob/master/disjob-registry/disjob-registry-etcd/src/main/java/cn/ponfee/disjob/registry/etcd/configuration/EtcdRegistryProperties.java">Etcd</a></li>
                    </ul>
                    <blockquote>
                        <p dir="auto">例如：若使用Consul做配置中心时，可加如下配置</p>
                    </blockquote>
                    <div class="highlight highlight-source-yaml notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="disjob.registry.consul:
  namespace: consul_namespace
  host: localhost
  port: 8500
  token:"><pre><span class="pl-ent">disjob.registry.consul</span>:
  <span class="pl-ent">namespace</span>: <span class="pl-s">consul_namespace</span>
  <span class="pl-ent">host</span>: <span class="pl-s">localhost</span>
  <span class="pl-ent">port</span>: <span class="pl-c1">8500</span>
  <span class="pl-ent">token</span>:</pre></div>
                    <ol start="6" dir="auto">
                        <li>一些内嵌的本地Server</li>
                    </ol>
                    <ul dir="auto">
                        <li><a href="https://github.com/dromara/disjob/blob/master/disjob-test/src/main/java/cn/ponfee/disjob/test/db/EmbeddedMysqlServerMariaDB.java">Mysql Server</a></li>
                        <li><a href="https://github.com/dromara/disjob/blob/master/disjob-test/src/main/java/cn/ponfee/disjob/test/redis/EmbeddedRedisServerKstyrc.java">Redis Server</a></li>
                        <li><a href="https://github.com/dromara/disjob/blob/master/disjob-registry/disjob-registry-zookeeper/src/test/java/cn/ponfee/disjob/registry/zookeeper/EmbeddedZookeeperServer.java">Zookeeper Server</a></li>
                        <li><a href="https://github.com/dromara/disjob/blob/master/disjob-registry/disjob-registry-consul/src/test/java/cn/ponfee/disjob/registry/consul/EmbeddedConsulServerPszymczyk.java">Consul Server</a></li>
                        <li><a href="https://github.com/dromara/disjob/blob/master/disjob-registry/disjob-registry-nacos/src/test/java/cn/ponfee/disjob/registry/nacos/EmbeddedNacosServerTestcontainers.java">Nacos Server</a>（依赖本地docker环境）</li>
                        <li><a href="https://github.com/dromara/disjob/blob/master/disjob-registry/disjob-registry-etcd/src/test/java/cn/ponfee/disjob/registry/etcd/EmbeddedEtcdServerTestcontainers.java">Etcd Server</a>（依赖本地docker环境）</li>
                    </ul>
                    <h1 tabindex="-1" dir="auto"><a id="user-content-example" class="anchor" aria-hidden="true" tabindex="-1" href="#example"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a>Example</h1>
                    <p dir="auto">举个简单的例子：统计在<code>(0，1万亿]</code>区间内质数的个数。如果单机单线程CPU去统计的话不知道要到何年马月，这里我们就可以使用<code>Disjob</code>框架提供的分布式并行执行的能力来解决该类问题。</p>
                    <ol dir="auto">
                        <li><strong>拆分任务</strong></li>
                    </ol>
                    <p dir="auto">先根据当前的机器资源情况来决定拆分任务的数量，比如我们有5台机器及每台2 core CPU(质数统计是CPU密集型)，决定拆分为10个任务。</p>
                    <ol start="2" dir="auto">
                        <li><strong>派发任务</strong></li>
                    </ol>
                    <p dir="auto">总任务被拆分成10个子任务后，框架会使用指定的路由算法把子任务派发给这些机器(Worker)。</p>
                    <ol start="3" dir="auto">
                        <li><strong>接收任务</strong></li>
                    </ol>
                    <p dir="auto">机器(Worker)接收到子任务后，会提交到框架的自定义线程池中执行。</p>
                    <ol start="4" dir="auto">
                        <li><strong>分布式并行执行</strong></li>
                    </ol>
                    <p dir="auto">在执行时我们可以使用分批次方式(通过代码循环)来统计，这里我们指定<code>task-1</code>在第一次循环统计<code>(0, 1亿]</code>，第二次循环统计<code>(10亿, 11亿]</code>，以此类推最后一次循环统计<code>(9990亿, 9991亿]</code>。同理其它的task也是按同样的方式分布式并行统计。</p>
                    <blockquote>
                        <p dir="auto">P.s. 黎曼猜想中可知质数分布是大体均匀的，判断一个数是否质数有很多方法，如埃氏筛法、欧拉筛法、Miller Rabin素性检验，这里我们可以使用Guava库提供的素性检验。</p>
                    </blockquote>
                    <ol start="5" dir="auto">
                        <li><strong>Savepoint</strong></li>
                    </ol>
                    <p dir="auto">如果在统计过程中机器宕机后怎么办？难道再从头开始统计吗？No No No！我们可以在每循环10次(或每隔执行超过1分钟)时使用<code>Savepoint</code>保存当前<code>task-1</code>的执行快照。宕机异常后的重新启动任务时会读取这份快照数据，从上一次的状态中接着继续统计。以下是<code>task-1</code>任务保存的快照数据样例</p>
                    <div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="{
  &quot;next&quot;: 4000000001, // 下一次循环时要统计的区间为(40亿, 41亿]
  &quot;count&quot;: 19819734,  // 已经统计到了 19819734 个质数
  &quot;finished&quot;: false   // 当前任务是否已经统计完成：true-是；false-否；
}"><pre><span class="pl-kos">{</span>
  <span class="pl-s">"next"</span>: <span class="pl-c1">4000000001</span><span class="pl-kos">,</span> <span class="pl-c">// 下一次循环时要统计的区间为(40亿, 41亿]</span>
  <span class="pl-s">"count"</span>: <span class="pl-c1">19819734</span><span class="pl-kos">,</span>  <span class="pl-c">// 已经统计到了 19819734 个质数</span>
  <span class="pl-s">"finished"</span>: <span class="pl-c1">false</span>   <span class="pl-c">// 当前任务是否已经统计完成：true-是；false-否；</span>
<span class="pl-kos">}</span></pre></div>
                    <ol start="6" dir="auto">
                        <li><strong>暂停与恢复</strong></li>
                    </ol>
                    <p dir="auto">假如我们的这几台机器资源需要临时做其它的事情，想把当前的统计任务暂停一段时间。No problem！框架是支持<code>暂停执行中的任务</code>，只需要在管理后台的<code>调度实例</code>页面，找到该任务点击<code>暂停</code>按钮即可。在暂停时任务会接收到一个中断信号，收到中断信号时同样可以在代码中使用<code>Savepoint</code>保存当前的执行快照。</p>
                    <p dir="auto">当其它事情处理完后，我们可以在管理后台的<code>调度实例</code>页面，找到被暂停的这个任务，点击<code>恢复</code>按钮，此时任务会从上一次保存的状态中恢复继续执行。</p>
                    <ol start="7" dir="auto">
                        <li><strong>自定义异常</strong></li>
                    </ol>
                    <p dir="auto">当某个子任务在执行过程中抛出框架自定义的<a href="https://github.com/dromara/disjob/blob/master/disjob-core/src/main/java/cn/ponfee/disjob/core/exception/PauseTaskException.java">PauseTaskException</a>则会<code>暂停</code>全部的10个子任务(包括派发在不同机器中的任务)，同理如果抛出<a href="https://github.com/dromara/disjob/blob/master/disjob-core/src/main/java/cn/ponfee/disjob/core/exception/CancelTaskException.java">CancelTaskException</a>则会<code>取消</code>全部的10个子任务。如果抛出其它类型的异常时，只会<code>取消</code>当前子任务，对应实例下的其它子任务不受影响。</p>
                    <ol start="8" dir="auto">
                        <li><strong>任务编排</strong></li>
                    </ol>
                    <p dir="auto">现在这个质数统计的总任务已经执行完了，共10个子任务，每个子任务都统计出了它的那部分结果。Disjob能自动帮我汇总结果吗？Yes！框架提供了非常强大且方便的表达式来编排任务，如：<code>A-&gt;B,C,(D-&gt;E)-&gt;D,F-&gt;G</code>，现在我们可以就创建一个汇总任务，然后再把这两个任务编排在一起。</p>
                    <p dir="auto">以下是本例中质数统计的job数据，只列了部分主要字段，其中<code>job_handler</code>为这两个任务处理器的编排(代码在项目源码中)</p>
                    <div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="{
  &quot;jobGroup&quot;: &quot;default&quot;,
  &quot;jobName&quot;: &quot;prime-count-dag&quot;,
  &quot;jobState&quot;: 1, // job状态：0-禁用；1-启用；
  &quot;jobType&quot;: 2,  // job类型：1-普通(Normal)；2-工作流(DAG)；
  &quot;jobHandler&quot;: &quot;cn.ponfee.disjob.test.handler.PrimeCountJobHandler -&gt; cn.ponfee.disjob.test.handler.PrimeAccumulateJobHandler&quot;,
  &quot;jobParam&quot;: &quot;{\&quot;m\&quot;:1,\&quot;n\&quot;:10000000000,\&quot;blockSize\&quot;:100000000,\&quot;parallel\&quot;:10}&quot;,
  &quot;triggerType&quot;: 2,
  &quot;triggerValue&quot;: &quot;2023-09-02 18:00:00&quot;
}"><pre><span class="pl-kos">{</span>
  <span class="pl-s">"jobGroup"</span>: <span class="pl-s">"default"</span><span class="pl-kos">,</span>
  <span class="pl-s">"jobName"</span>: <span class="pl-s">"prime-count-dag"</span><span class="pl-kos">,</span>
  <span class="pl-s">"jobState"</span>: <span class="pl-c1">1</span><span class="pl-kos">,</span> <span class="pl-c">// job状态：0-禁用；1-启用；</span>
  <span class="pl-s">"jobType"</span>: <span class="pl-c1">2</span><span class="pl-kos">,</span>  <span class="pl-c">// job类型：1-普通(Normal)；2-工作流(DAG)；</span>
  <span class="pl-s">"jobHandler"</span>: <span class="pl-s">"cn.ponfee.disjob.test.handler.PrimeCountJobHandler -&gt; cn.ponfee.disjob.test.handler.PrimeAccumulateJobHandler"</span><span class="pl-kos">,</span>
  <span class="pl-s">"jobParam"</span>: <span class="pl-s">"{\"m\":1,\"n\":10000000000,\"blockSize\":100000000,\"parallel\":10}"</span><span class="pl-kos">,</span>
  <span class="pl-s">"triggerType"</span>: <span class="pl-c1">2</span><span class="pl-kos">,</span>
  <span class="pl-s">"triggerValue"</span>: <span class="pl-s">"2023-09-02 18:00:00"</span>
<span class="pl-kos">}</span></pre></div>
                    <blockquote>
                        <p dir="auto">本例中的质数统计流程图如下</p>
                    </blockquote>
                    <p dir="auto"><a target="_blank" rel="noopener noreferrer" href="https://github.com/dromara/disjob/blob/master/docs/images/example-flow.png"><img src="https://raw.githubusercontent.com/dromara/disjob/master/docs/images/example-flow.png" alt="范例流程图" style="max-width: 100%;"></a></p>
                    <h2 tabindex="-1" dir="auto"><a id="user-content-contributing" class="anchor" aria-hidden="true" tabindex="-1" href="#contributing"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a>Contributing</h2>
                    <p dir="auto">如有发现bug、更优的实现方案、新特性等，可提交PR或新建<a href="/dromara/disjob/issues">Issues</a>。</p>
                    <h2 tabindex="-1" dir="auto"><a id="user-content-communication" class="anchor" aria-hidden="true" tabindex="-1" href="#communication"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a>Communication</h2>
                    <p dir="auto">扫码添加微信好友，备注：disjob，邀您加入群聊</p>
                    <p dir="auto"><a target="_blank" rel="noopener noreferrer" href="https://github.com/dromara/disjob/blob/master/docs/images/wechat.jpg"><img src="https://raw.githubusercontent.com/dromara/disjob/master/docs/images/wechat.jpg" width="230" alt="Wechat group" style="max-width: 100%;"></a></p>
                    <h2 tabindex="-1" dir="auto"><a id="user-content-todo-list" class="anchor" aria-hidden="true" tabindex="-1" href="#todo-list"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a>Todo List</h2>
                    <ul class="contains-task-list">
                        <li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> 扩展注册中心：Zookeeper、Etcd、Nacos</li>
                        <li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> 工作流任务(Workflow DAG)</li>
                        <li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> 管理后台、账户体系及权限控制</li>
                        <li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox"> 搭建一个关于项目使用说明的文档站点</li>
                        <li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox"> 在线查看任务实时运行日志</li>
                        <li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox"> 告警订阅：邮件、短信、电话、飞书、钉钉、微信</li>
                        <li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox"> 可视化监控BI(Dashboard)</li>
                        <li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox"> 增加多种Savepoint的支持：File System、Hadoop、RocksDB</li>
                    </ul>
                </article>
            </div>
        </div>

    </readme-toc>











</div>

</body>
</html>
